﻿using System;
using System.Linq;
using System.IO.Ports;
using System.Collections;
using e77.Ud2;
using e77.Ud2.HeadEnums;
using System.Collections.Generic;
using System.ComponentModel;


namespace Szakdolgozat
{

    // az interface megvalósítása UI és Controller közt
    public class Controller : IController
    {
        SerialPort serialport = new SerialPort();
        Database database = new Database();
        Command command = new Command();
        LabStripU11 strip = new LabStripU11();
        Dictionary<EColors, double> Results = new Dictionary<EColors, double>();

        public static int operatorid = -1;
        string measurementtable = "measurement";
        string operatorstable = "operators";
        string resulttable = "results";


        // ellenőrzi a függvény, hogy autologin-ról van-e szó, ha igen, pw nélkül is be lehet jelentkezni
        public bool AutologinCheck(string username)
        {
            if (username == "autologin")
                return true;
            else
                return false;
        }


        // folyamatos ellenőrzés, státuszsorba
        public bool GetStatus()
        {
            return true;
        }

        // valami kezdőértéket kap az eredményeket tartalmazó dictionary
        void InitResults(Dictionary<string, string> Results)
        {
            if (Results.Count == 0)
            {
                Results.Add("Conv", "");
                Results.Add("SI", "");
                Results.Add("Arb", "");
            }
        }

        //a mérés metódusa
        public void Measure(string sampleID, string patientID, string stripLOTID)
        {

            Command command = new Command();
            Measure measure = new Measure();
            Result result = new Result();
            ResultText resultText = new ResultText();
            Database database = new Database();

            Dictionary<EColors, double> LEDResultsDict;
            Dictionary<string, string> Results = new Dictionary<string, string>();

            byte[] databack;
            byte[] rawdata;
            string message;
            int index;
            string categoryunit;
            double cutoff = -1;     // ilyen köztes eredmény biztosan nem lehet

            string unitconv;
            string unitsi;
            string unitarb;
            string UnitConv = "Conv";
            string UnitSI = "SI";
            string UnitArb = "Arb";

            InitResults(Results);
            database.InsertDatabase("measurement", "measure_id,patient_id,strip_id", sampleID, patientID, stripLOTID);

            // fej végigléptetése a pad-eken
            foreach (var padpos in strip.Orig_Strip.PadPositions)
            {
                databack = command.PosStep(padpos.Value);
                Strip.EPadNames padname;
                string padName;

                // csak azt kell lemérni, aminek az EPad key-e P-vel kezdődik
                if (padpos.Key.ToString().StartsWith("P"))
                {
                    ELedMask mask;
                    // szükség van a pad-nek a nevére, hogy a maszkot elő lehessen állítani
                    padName = Enum.GetName(typeof(Strip.EPadNames), (int)padpos.Key);
                    padname = (Strip.EPadNames)Enum.Parse(typeof(Strip.EPadNames), padName);
                    if (e77.Ud2.Strip.Instance.eledDict.ContainsKey(padname))
                    {
                        mask = Strip.Instance.eledDict[padname];
                    }
                    else
                        mask = ELedMask.AllOff;

                    // nyers adatok kinyerése a mérés után
                    rawdata = command.PosMeasure(mask);
                    // pad-től függő kiszámítása a köztes eredménynek
                    message = measure.measurecomp(rawdata, padname, out cutoff, out LEDResultsDict);

                    ///// TO DO!!!!
                    if (message == "overlit channel")
                        Console.WriteLine("overlit channel");
                    else if (message == "LED error")
                        Console.WriteLine("LED error");
                    else if (message == "error")
                        Console.WriteLine("error");


                    // sikerült a megfelelő cutoff értéket kiválasztani
                    if (message == "result" && padName != "Comp")
                    {
                        // a cutoff-hoz megvan a köztes eredmény
                        index = result.ResultIndex(padname, cutoff);
                        // mértékegységekhez tartozó táblázatokból a megfelelő érték kiválasztása is megtörténik
                        // unit... változókban a mértékegység tárolódik (kell a kiíratáshoz)
                        categoryunit = resultText.GetResult(UnitConv, padName, index, out unitconv);
                        Results["Conv"] = categoryunit + unitconv;
                        Results["SI"] = resultText.GetResult(UnitSI, padName, index, out unitsi) + unitsi;
                        // Arb esetén nincs szükség mértékegységre
                        Results["Arb"] = resultText.GetResult(UnitArb, padName, index, out unitarb);

                        // adatbázisba való mentés
                        database.InsertDatabase("results", "measure_id,padname,green_led,cyan_led,orange_led,red_led,result_conv, result_si,result_arb",
                            sampleID, padName, LEDResultsDict[EColors.green], LEDResultsDict[EColors.cyan], LEDResultsDict[EColors.orange],
                            LEDResultsDict[EColors.red], Results["Conv"], Results["SI"], Results["Arb"]);

                    }

                }

            }

            command.StepInit();
        }


        public class Data : INotifyPropertyChanged
        {
            string _measure_id;
            public string Measure_idPropertyName = "Measure_id";
            public string Measure_id
            {
                get { return _measure_id; }
                set
                {
                    _measure_id = value;
                    RaisePropertyChanged(Measure_idPropertyName);
                }
            }

            string _datetime;
            public string DateTimePropertyName = "DateTime";
            public string DateTime
            {
                get { return _datetime; }
                set
                {
                    _datetime = value;
                    RaisePropertyChanged(DateTimePropertyName);
                }
            }

            string _padName;
            public string PadNamePropertyName = "PadName";
            public string PadName
            {
                get { return _padName; }
                set
                {
                    _padName = value;
                    RaisePropertyChanged(PadNamePropertyName);
                }
            }

            string _resultConv;
            public string ResultConvPropertyName = "ResultConv";
            public string ResultConv
            {
                get { return _resultConv; }
                set
                {
                    _resultConv = value;
                    RaisePropertyChanged(ResultConvPropertyName);
                }
            }

            string _resultSi;
            public string ResultSIPropertyName = "ResultSI";
            public string ResultSI
            {
                get { return _resultSi; }
                set
                {
                    _resultSi = value;
                    RaisePropertyChanged(ResultSIPropertyName);
                }
            }

            string _resultArb;
            public string ResultArbPropertyName = "ResultArb";
            public string ResultArb
            {
                get { return _resultArb; }
                set
                {
                    _resultArb = value;
                    RaisePropertyChanged(ResultArbPropertyName);
                }
            }

            public Data(string measure_id, object date_time, string padname, string result_conv, string result_si, string result_arb)
            {
                this._measure_id = measure_id;
                this._datetime = (string) date_time;
                this._padName = padname;
                this._resultConv = result_conv;
                this._resultSi = result_si;
                this._resultArb = result_arb;
            }

            public Data()
            { }

            public event PropertyChangedEventHandler PropertyChanged;
     
            protected void RaisePropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
        }

        /// <summary>
        /// az adatbázisból lekérő metódus egy List-el tér vissza, első x elemként ( ahány darab oszlop van ), 
        /// visszatér az oszlopok nevével majd végiglépked az összes soron ---> az adatok feldolgozása az oszlopol számából lesz 
        /// megadható--> a lekérendő oszlopok string-ként adottak, vesszővel vannak elválasztva, meg lehet kapni az oszlopok
        /// számát, ha ezt a string-et felbontom a separator char[] szerint ( String.Split metódus) és megmondom,
        /// hány eleme van a visszaadott string[]-nek
        /// </summary>
        /// <param name="measureID"></param>
        /// <returns></returns>
        public List<Data> GetResults(string measureID)
        {

            List<object> DBlist = new List<object>();

            string columns = "measurement.measure_id,measurement.date_time,results.padname,results.result_conv,results.result_si,results.result_arb";
            string condition1 = "measurement.measure_id=results.measure_id";
            string condition2 = "results.measure_id=" + String.Format("'{0}'", measureID);
            char[] separator = { ',' };
            string[] col = columns.Split(separator);

            int columnNo = col.Length;
            
            database.Query(measurementtable, resulttable, columns, condition1, condition2, out DBlist);

            List<Data> data = new List<Data>();

            for (int i = 2 * columnNo - 1; i < DBlist.Count; i+=columnNo)
            {
                if ((i % columnNo) == (columnNo - 1))
                {
                    // Data konstruktora 6 adatra van megírva
                    data.Add(new Data(DBlist[i - 5].ToString(), DBlist[i - 4].ToString(), DBlist[i - 3].ToString(),
                                        DBlist[i - 2].ToString(), DBlist[i - 1].ToString(), DBlist[i].ToString()));
                }
            }

            return data;

        }

        public List<Data> GetResults()
        {

            List<object> DBlist = new List<object>();

            string columns = "measurement.measure_id,measurement.date_time,results.padname,results.result_conv,results.result_si,results.result_arb";
            string condition = ".measure_id=measurement.measure_id";
            char[] separator = { ',' };
            string[] col = columns.Split(separator);

            int columnNo = col.Length;
            // az adatbázisból lekérő metódus egy List-el tér vissza, első x elemként ( ahány darab oszlop van ), 
            // visszatér az oszlopok nevével majd végiglépked az összes soron ---> az adatok feldolgozása az oszlopol számából lesz 
            // megadható--> a lekérendő oszlopok string-ként adottak, vesszővel vannak elválasztva, meg lehet kapni az oszlopok
            // számát, ha ezt a string-et felbontom a separator char[] szerint ( String.Split metódus) és megmondom,
            // hány eleme van a visszaadott string[]-nek
            database.Query(resulttable, measurementtable, columns, condition, out DBlist, false);

            List<Data> data = new List<Data>();

            for (int i = 0; i < DBlist.Count; i++)
            {
                if ((i % columnNo) == (columnNo - 1))
                {
                    // Data konstruktora 6 adatra van megírva
                    data.Add(new Data(DBlist[i - 5].ToString(), DBlist[i - 4].ToString(), DBlist[i - 3].ToString(),
                                        DBlist[i - 2].ToString(), DBlist[i - 1].ToString(), DBlist[i].ToString()));
                    
                }
            }

            return data;

        }

        public int GetOperatorId(string operatorname)
        {
            object op_id;
            database.Query(operatorstable, "operator_id", "operator_name=" + String.Format("'{0}'", operatorname), out op_id) ;
            return (int)op_id;
        }



        //.....---------------------------------------------------------------
        public void AllLEDOn()
        {
            command.Send(ECommand.LedOn, ELedMask.AllOn);
            command.Receive();
        }



        //.....---------------------------------------------------------------

        //public void NewMeasure(string sampleID, string PatientID, string StripID, string comment)
        //{
        //    if ( String.IsNullOrWhiteSpace(sampleID))
        //    database.InsertDatabase(
             

        //}


    }
}
